package org.kinglone.basic.utils;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.web.util.HtmlUtils;

/**
 * 
 * 名称： StringUtil
 * <br>描述：	
 */
public abstract class StringUtil extends org.springframework.util.StringUtils {

    private static final Log logger = LogFactory.getLog(StringUtil.class);

    public static boolean isNullOrEmpty(String string) {
        if (string == null || string.trim().equals("")) {
            return true;
        }
        return false;
    }

    public static boolean containInArray(String target, String[] list) {
        for (String dest : list) {
            if (dest.equals(target)) {
                return true;
            }
        }
        return false;
    }

    /**	
     * <p>Description:简单的字段串连接</p>
     * <p>Create Time: 2008-10-6   </p>
     * @param strs
     * @return
     */
    public static String join(String... strs) {
        return org.apache.commons.lang.StringUtils.join(strs);
    }

    public static String truncateMessage(String description, int length) {
        Assert.state(length > 0);
        if (description != null && description.length() > length) {
            logger.debug("Truncating long message, original message is: " + description);
            return description.substring(0, length);
        }
        else {
            return description;
        }
    }

    /**
     * 将字符串转义为带格式的HTML
     * @param tempMsg
     * @return 带格式的HTML
     */
    public static String wrapForHtml(String tempMsg) {
        if (isNullOrEmpty(tempMsg)) {
            return tempMsg;
        }
        tempMsg = HtmlUtils.htmlEscape(tempMsg);
        tempMsg = tempMsg.replaceAll("\r\n", "<br/>");
        tempMsg = tempMsg.replaceAll("\n", "<br/>");
        tempMsg = tempMsg.replaceAll("\r", "<br/>");
        return tempMsg.replaceAll(" ", "&nbsp;");
    }

    /**
     * 将日期转化为字符串
     * 
     * @param str
     * @param pattern
     * @return
     */
    public static String dateToStr(Date date, String pattern) {
        SimpleDateFormat formater = new SimpleDateFormat(DateUtils.NORMAL_DATE_FORMAT);
        if (pattern != null)
            formater.applyPattern(pattern);
        return formater.format(date);
    }

    /**
     * 分割参数
     * 
     * @param paraSrc
     *            String
     * @param sepa
     *            String
     * @return Map sample : "a=b,c=d,..."
     */
    public static Map<String, String> splitPara(String paraSrc, String sepa) {
        if (paraSrc == null || paraSrc.trim().length() == 0) {
            return null;
        }

        LinkedHashMap<String, String> paraMap = new LinkedHashMap<String, String>();
        if (sepa == null || sepa.equals("")) { // 默认分割参数的分隔符为 ","
            sepa = ",";
        }

        /**
         * 
         */
        String[] paras = paraSrc.split(sepa);
        for (int i = 0, j = 0; i < paras.length; i++) {
            String tmpResult[] = paras[i].split("=");
            if (tmpResult.length >= 2) { // 2 a=b
                paraMap.put(tmpResult[0].trim(), tmpResult[1]);
            }
            else if (tmpResult.length == 1) {
                if (paras[i].indexOf("=") >= 0) { // 1 a=
                    paraMap.put(tmpResult[0].trim(), "");
                }
                else { // 0 a
                    paraMap.put("TEXT." + j, paras[i]);
                    j++;
                }
            }
        }

        return paraMap;
    }

    /**
     * return String basename
     * 
     * @param name
     *            String
     * @param split
     *            String
     * @return String com.xxx.ne --> ne
     */
    public static String pathname(String name, String split) {
        if (name == null || name.equals("")) {
            return "";
        }
        if (split == null || split.equals("")) {
            split = ".";
        }

        int index = name.lastIndexOf(split);
        if (index >= 0) {
            return name.substring(0, index);
        }

        return name;
    }

    /**
     * return String basename
     * 
     * @param name
     *            String
     * @param split
     *            String
     * @return String com.xxx.ne --> ne
     */
    public static String basename(String name, String split) {
        if (name == null || name.equals("")) {
            return "";
        }
        if (split == null || split.equals("")) {
            split = ".";
        }

        int index = name.lastIndexOf(split);
        if (index >= 0) {
            return name.substring(index + split.length());
        }

        return "";
    }

    /**
     * 替换符合正则表达式的所有子字符串为新字符串
     * 
     * @param src
     *            String
     * @param pattern
     *            String
     * @param to
     *            String
     * @return String
     */
    public static String replaceAll(String src, String pattern, String to) {
        if (src == null) {
            return null;
        }
        if (pattern == null) {
            return src;
        }

        StringBuffer sb = new StringBuffer();
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(src);

        int i = 1;
        while (m.find()) {
            // System.out.println("找到第" + i + "个匹配:" + m.group() +
            // " 位置为:" + m.start() + "-" + (m.end() - 1));
            m.appendReplacement(sb, to);
            i++;
        }
        m.appendTail(sb);
        return sb.toString();
    }

    /**
     * 返回某字符串中所有符合正则表达式的子字符串，以字符串数组形式返回
     * 
     * @param src
     *            String
     * @param pattern
     *            String
     * @return String[]
     */
    public static String[] findAll(String src, String pattern) {
        return findAll(src, pattern, 0);
    }

    /**	
     * <p>Description:              </p>
     * <p>Create Time: 2009-12-23   </p>
    
     * @param src
     * @param pattern
     * @param flags
     *         Match flags, see Pattern.compile(pattern,flags)
     * @return
     */
    public static String[] findAll(String src, String pattern, int flags) {

        if (src == null) {
            return new String[0];
        }
        if (pattern == null) {
            return new String[0];
        }

        Pattern p = Pattern.compile(pattern, flags);
        Matcher m = p.matcher(src);
        Collection<String> l = new ArrayList<String>();
        while (m.find()) {
            l.add(m.group());
        }

        return (String[]) l.toArray(new String[] {});

    }

    /**
     * 是否字符串匹配
     * 
     * @param src
     *            String
     * @param regexp
     *            String
     * @return boolean
     */
    public static boolean match(String src, String regexp) {
        Pattern p = Pattern.compile(regexp);
        Matcher m = p.matcher(src);
        return m.find();
        // return m.matches(); 090413 modified

    }

    @SuppressWarnings("unchecked")
    public final static boolean verifyEmail(String email) {
        if (email == null) {
            return false;
        }
        int at = email.indexOf('@');
        int dot = email.indexOf('.');
        if (at < 1) {
            return false;
        }
        if(dot<=0 || dot==(email.length() - 1)){
            return false;
        }
        if(at + 1 == dot){
            return false;
        }
        try {
            Class mailClass = null;
            try {
            	
                mailClass =ClassUtils.forName("javax.mail.internet.InternetAddress", ClassUtils.class.getClassLoader());
            } catch (ClassNotFoundException ex) {
            } catch (NoClassDefFoundError ex) {
            }
            if(mailClass != null){
                Constructor c = mailClass.getConstructor(String.class);
                c.newInstance(email);
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    public static Locale toLocale(String locale){
        if(StringUtil.hasText(locale)){
            String[] values = null;
            if(locale.indexOf("_") > 0){
                values = split(locale, "_");
            }
            else if(locale.indexOf("-") > 0){
                values = split(locale, "-");
            }
            else{
                values = new String[0];
            }
            if(values.length == 1){
                return new Locale(values[0]);
            }
            if(values.length == 2){
                return new Locale(values[0], values[1]);
            }
            if(values.length == 3){
                return new Locale(values[0], values[1], values[2]);
            }
        }
        return null; 
    }
    public static boolean equals(String str1, String str2){
    	return org.apache.commons.lang.StringUtils.equals(str1, str2);
    } 
    
    public static boolean isEmptyString(String str) {
		return str == null || str.length() == 0;
	}

	public static boolean isNotEmpty(String str) {
		return !isEmptyString(str);
	}

	/**
	 * ��byte����ת��Ϊ16���Ƶ���ֵ��ʾ����ʽ������ʹ��ǰ׺
	 * 
	 * @param ba ��Ҫת����byte����
	 * @return String 16���Ʊ�ʾ���ַ�
	 */
	public static String bytesToHexString(byte[] ba) {
		return bytesToHexString(ba, "");
	}

	/**
	 * btye转16进制
	 * @param ba
	 * @param prefix
	 * @return
	 */
	public static String bytesToHexString(byte[] ba, String prefix) {
		if ((ba == null) || (prefix == null)) { throw new NullPointerException(); }

		StringBuffer sb = new StringBuffer();
		sb.append(prefix);
		for (int i = 0; i < ba.length; i++) {
			int vi = ba[i];
			if (vi < 0) {
				vi += 256;
			}
			if (vi < 0x10) {
				sb.append("0");
			}
			sb.append(Integer.toHexString(vi));
		}
		return sb.toString();
	}

	/**
	 * 16进制byte
	 * @param hexStr
	 * @return
	 */
	public static byte[] hexStringToBytes(String hexStr) {
		return hexStringToBytes(hexStr, "");
	}

	/**
	 * 16进制byte
	 * @param hexStr
	 * @return
	 */
	public static byte[] hexStringToBytes(String hexStr, String prefix) {
		if ((hexStr == null) || (prefix == null)) { throw new NullPointerException(); }
		String myHexStr = hexStr.trim();
		if (myHexStr.startsWith(prefix)) {
			myHexStr = myHexStr.substring(prefix.length());
		}
		// if (myHexStr.length() % 2 != 0) {
		// throw new NumberFormatException();
		// }
		int myHexStrLen = myHexStr.length();
		byte[] ba = new byte[myHexStrLen / 2];
		for (int i = 0; i < myHexStrLen; i += 2) {
			int vi = Integer.parseInt(myHexStr.substring(i, i + 2), 16);
			if (vi > 128) {
				vi -= 256;
			}
			ba[i / 2] = (byte) vi;
		}
		return ba;
	}

	/**
	 * int转byte
	 * @param i
	 * @return
	 */
	public static byte[] intToByte4(int i) {
		byte[] abyte0 = new byte[4];
		abyte0[3] = (byte) (0xff & i);
		abyte0[2] = (byte) ((0xff00 & i) >> 8);
		abyte0[1] = (byte) ((0xff0000 & i) >> 16);
		abyte0[0] = (byte) ((0xff000000 & i) >> 24);
		return abyte0;
	}

	/**
	 * short转byte
	 * @param i
	 * @return
	 */
	public static byte[] shortToByte2(short i) {
		byte[] abyte0 = new byte[2];
		abyte0[1] = (byte) (0xff & i);
		abyte0[0] = (byte) ((0xff00 & i) >> 8);

		return abyte0;
	}

	/**
	 * byte转int
	 * @param b
	 * @return
	 */
	public static int byte4ToInt(byte[] b) {
		int i = ((((b[0] & 0xff) << 8 | (b[1] & 0xff)) << 8) | (b[2] & 0xff)) << 8 | (b[3] & 0xff);
		return i;
	}

	/**
	 * byte转short
	 * @param b
	 * @return
	 */
	public static short byte2ToShort(byte[] b) {
		short i = (short) (((b[0] & 0xff) << 8 | (b[1] & 0xff)) << 8);
		return i;
	}

	/**
	 * Stringת����UTF-8�����ַ�����
	 * 
	 * @param str
	 * @return byte[]
	 */
	public static byte[] getUtf8Bytes(String str) {
		try {
			return str.getBytes("UTF-8");
		} catch (UnsupportedEncodingException uee) {
			return str.getBytes();
		}
	}

	/**
	 * UTF-8��ʽ�ַ�����ת����String
	 * 
	 * @param utf8
	 * @return String
	 */
	public static String getStringFromUtf8(byte[] utf8) {
		try {
			return new String(utf8, "UTF-8");
		} catch (UnsupportedEncodingException uee) {
			return new String(utf8);
		}
	}

	/**
	 * ��list�е�ֵʹ�ö���ƴ����4����
	 * 
	 * @param list
	 * @return String
	 */
	@SuppressWarnings("unchecked")
	public static String toString(List list) {
		if (list == null) { return ""; }
		StringBuffer stringBuffer = new StringBuffer(256);
		for (Iterator iter = list.iterator(); iter.hasNext();) {
			stringBuffer.append((String) iter.next());
			if (iter.hasNext()) {
				stringBuffer.append(",");
			}
		}
		return stringBuffer.toString();
	}

	/**
	 * �������е�ֵʹ�ö���ƴ����4����
	 * 
	 * @param list
	 * @return String
	 */
	public static String toString(Object[] objs) {
		if (objs == null || objs.length == 0) { return ""; }
		return toString(Arrays.asList(objs));
	}

	/**
	 * ��bigdecimalת��ΪTB��GB��MB����ʽ����String������ΪMB
	 * 
	 * @param list
	 * @return String
	 */
	public static String mbToTGM(BigDecimal mb) {
		StringBuffer sb = new StringBuffer(200);
		int g = 0;
		int t = 0;
		float m = 0;

		t = new Float(mb.divide(new BigDecimal(1024 * 1024), BigDecimal.ROUND_DOWN).floatValue()).intValue();
		mb = mb.subtract((new BigDecimal(t).multiply(new BigDecimal(1024 * 1024))));
		g = new Float(mb.divide(new BigDecimal(1024), BigDecimal.ROUND_DOWN).floatValue()).intValue();
		mb = mb.subtract((new BigDecimal(g).multiply(new BigDecimal(1024))));
		m = mb.floatValue();

		sb.append(new Integer(t).toString()).append(" TB ");
		sb.append(new Integer(g).toString()).append(" GB ");
		sb.append(new Float(m).toString()).append(" MB ");

		return sb.toString();
	}

	/**
	 * by yangxw in 2008.03.06 �ַ��滻����
	 * 
	 * @param con ��Ҫ�����滻��ԭ4�ַ�
	 * @param tag Ҫ���滻���ַ�
	 * @param rep �滻�ɵ��ַ�
	 * @return �滻�������µĵ��ַ�
	 */
	public static String str_replace(String con, String tag, String rep) {
		int j = 0;
		int i = 0;
		String RETU = "";
		String temp = con;
		int tagc = tag.length();
		while (i < con.length()) {
			if (con.substring(i).startsWith(tag)) {
				temp = con.substring(j, i) + rep;
				RETU += temp;
				i += tagc;
				j = i;
			} else {
				i += 1;
			}
		}
		RETU += con.substring(j);
		return RETU;
	}

	/**
	 * by mengrj 2008-08-01 �ַ�a���Ƿ�����ַ�b���е��ַ�
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public static boolean isContainChar(String a, String b) {
		if (a == null || b == null) return false;
		char[] bset = b.toCharArray();
		for (int i = 0; i < bset.length; i++) {
			for (int j = 0; j < a.length(); j++) {
				if (bset[i] == a.charAt(j)) return true;
			}
		}
		return false;
	}

	/**
	 * ȥ��HTML��ǣ����ش��ı�
	 * 
	 * @author chenhh
	 * @param htmlStr Ҫת��HTML�ı�
	 * @return String ת����Ĵ��ı�
	 */
	public static String htmlToStr(String htmlStr) {
		String regEx = "<\\s*img\\s+([^>]+)\\s*>";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(htmlStr);
		return m.replaceAll("").replace("&nbsp;", "");
	}

	public static String upperCase(String s) {
		return s == null ? null : s.toUpperCase();
	}

	public static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("[0-9]*");
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) { return false; }
		return true;
	}

	public static boolean isSameByTrim(String str1, String str2) {
		if (str1 == null || str1 == null) { return false; }
		return str1.trim().equals(str2.trim());
	}

	public static String bytesToHexStringForDebug(byte[] ba, String prefix) {
		if ((ba == null) || (prefix == null)) { return "null"; }

		StringBuffer sb = new StringBuffer();
		sb.append(prefix);
		for (int i = 0; i < ba.length; i++) {
			sb.append(" ");
			int vi = ba[i];
			if (vi < 0) {
				vi += 256;
			}
			if (vi < 0x10) {
				sb.append("0");
			}
			sb.append(Integer.toHexString(vi));

		}
		return sb.toString();
	}

	// add by zhoubengang ��ȡ�����ַ�
	public static String substring(String str, int toCount, String more) {
		int reInt = 0;
		String reStr = "";
		if (str == null) return "";
		char[] tempChar = str.toCharArray();
		for (int kk = 0; (kk < tempChar.length && toCount > reInt); kk++) {
			String s1 = String.valueOf(tempChar[kk]);
			byte[] b = s1.getBytes();
			reInt += b.length;
			reStr += tempChar[kk];
		}
		if (toCount == reInt || (toCount == reInt - 1)) reStr += more;
		return reStr;
	}

	/**
	 * 
	 * 描述：转换为整数
	 * 
	 * @param val
	 * @param defaultVal
	 * @return
	 * @version: 1.0
	 * @date: 2011-8-24 上午10:45:15
	 */
	public static Integer toInteger(String val, Integer defaultVal) {
		Integer result = defaultVal;
		try {
			result = Integer.parseInt(val);
		} catch (Exception e) {
		}
		return result;
	}

	/**
	 * 
	 * 描述：转换为浮点数
	 * 
	 * @param val
	 * @param defaultVal
	 * @return
	 * @version: 1.0
	 * @date: 2011-8-24 上午10:46:30
	 */
	public static Double toDouble(String val, Double defaultVal) {
		Double result = defaultVal;
		try {
			result = Double.parseDouble(val);
		} catch (Exception e) {
		}
		return result;
	}

	/**
	 * 
	 * 描述：处理空字符串，如果是空字符串则返回默认值
	 * 
	 * @param val
	 * @param defaultVal
	 * @return
	 * @version: 1.0
	 * @date: 2011-8-24 上午10:50:53
	 */
	public static String ofEmpty(String val, String defaultVal) {
		String result = val;
		if (val == null || val.length() == 0) {
			result = defaultVal;
		}
		return result;
	}
	/**
	 *  描述：处理空字符串，如果是空字符串则返回 ""
	 * @param val
	 * @return
	 */
	public static String noEmpty(String val){
		String result = val;
		if (val == null || val.length() == 0) {
			result = "";
		}
		return result;
	}
	/**
	 * 获取uuid
	 * @return
	 */
	public static String getUUID(){
		return UUID.randomUUID().toString().replace("-","");
	}
	
	/**  
     * 元转换为分.  
     *   
     * @param yuan  
     *            元  
     * @return 分  
     */  
    public static String fromYuanToFen(final String amount) {  
    	String currency =  amount.replaceAll("\\$|\\￥|\\,", "");  //处理包含, ￥ 或者$的金额  
        int index = currency.indexOf(".");  
        int length = currency.length();  
        Long amLong = 0l;  
        if(index == -1){  
            amLong = Long.valueOf(currency+"00");  
        }else if(length - index >= 3){  
            amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));  
        }else if(length - index == 2){  
            amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);  
        }else{  
            amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");  
        }  
        return amLong.toString();  
    } 
    
    public static void main(String args[]) {
        System.out.println(StringUtil.match("SMP#", "#"));// false ?
        System.out.println(StringUtil.match("SMP#", ".*?#"));// true
        System.out.println(StringUtil.match("\r\nff P720 login:", ".*?name:|.*?ogin:"));// false
        System.out.println(StringUtil.verifyEmail("linyiming@ruijie.com.cn"));
        System.out.println(StringUtil.verifyEmail("x@.com"));
        // ?
    }

}
